<template>
  <div class="image-viewer-webpart">
    <!-- 顶部信息 -->
    <div class="webpart-head">
      <div class="head-left" :title="imageTitle">
        <i class="el-icon-picture-outline" />{{ imageTitle }}
      </div>
      <div class="head-right">
        <i class="el-icon-download" title="下载" @click="onCallbackFn('download')" v-if="isIconDownload" />
        <i class="el-icon-files" :class="showRightList ? 'head-right-hover' : '' " title="图片列表" @click="showRightList = !showRightList"/>
        <i class="el-icon-close" title="关闭" @click="onCallbackFn('close')" />
      </div>
    </div>
    <!-- 上一张 -->
    <div class="webpart-nav-main image-upper-main" title="上一张" @click="onSwitchChange('upper')">
      <i class="el-icon-arrow-left"/>
    </div>
    <!-- 下一张 -->
    <div class="webpart-nav-main image-next-main" title="下一张" @click="onSwitchChange('next')" :style="{ right: showRightList ? 300 + 'px' : 0}">
      <i class="el-icon-arrow-right"/>
    </div>
    <!-- 图片容器 -->
    <div class="webpart-image-cont" :style="{ width: showRightList ? imageWidth - 300 + 'px' : '100%' }">
      <i class="el-icon-loading" v-if="iconLoading"/>
      <img :src="imageUrl" alt="" id="imageContID"/>
    </div>
    <!-- 底部工具栏 -->
    <div class="webpart-footer-main">
      <i class="el-icon-zoom-in" title="放大" @click="onScaleFn('large')" />
      <i class="el-icon-zoom-out" title="缩小" @click="onScaleFn('small')"/>
      <i class="el-icon-refresh-right" title="向右旋转" @click="onRotateFn('right')" />
      <i class="el-icon-refresh-left" title="向左旋转" @click="onRotateFn('left')" />
      <i class="el-icon-position" title="在新的浏览器窗口打开" @click="onOpenFn()"/>
      <i class="el-icon-refresh" title="还原" @click="onReductionFn()"/>
    </div>
    <!-- 右侧列表 -->
    <div class="webpart-right-list" :style="showRightList ? 'right: 0' : 'right: -300px'">
      <div class="list-head">
        <div class="lh-left">
          <i class="el-icon-menu"/>图片列表
        </div>
        <div class="lh-right">
          {{ imageIndex + 1 }} / {{ isImageList.length }}
        </div>
      </div>
      <div class="list-main">
        <div class="image-list"
             :class="imageIndex === index ? 'image-list-hover' : ''"
             v-for="(item, index) in isImageList"
             :key="index"
             :id="'list' + index"
             @click="onRightImageChange(item, index)">
          <img :src="item.isUrl" alt=""/>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: 'ElImageViewer',
  props: {
    isImageList: {
      type: Array,
      default: () => []
    },
    isImageData: {
      type: Object,
      default: () => {}
    },
    isIconDownload: {
      type: Boolean,
      default: false
    },
    showRightList: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      // 图片主体
      imageEl: null,
      imageUrl: '',
      imageTitle: '',
      // 主容器相关参数
      imageWidth: window.innerWidth,
      // 右侧列表
      imageIndex: 0,
      // 图片操作相关参数
      offsetX: 0,
      offsetY: 0,
      rotateIndex: 0,
      scaleIndex: 0,
      // 加载图标
      iconLoading: false,
    }
  },
  watch: {
    imageUrl () {
      this.$nextTick(() => {
        this.infoImageWidthFn ()
        this.infoScrollIntoViewFn(document.getElementById('list' + this.imageIndex))
      })
    }
  },
  mounted() {
    this.infoImageFn ()
  },
  methods: {
    // 初始化
    infoImageFn () {
      if (this.isImageList.length > 0) {
        document.body.style.overflow = 'hidden'
        // 图片
        this.imageUrl = this.isImageData.imageUrl
        // 标题
        this.imageTitle = this.isImageData.imageTitle
        // 右侧列表的索引显示
        this.imageIndex = this.isImageData.imageIndex
        window.addEventListener('resize', this.onResizeFn)
        this.imageEl = document.getElementById("imageContID")
        this.onPositionImgFn ()
        this.onRollerFn ()
      }
    },

    // 右侧列表点击事件
    onRightImageChange (item, index) {
      // 主容器
      this.imageUrl = item.isUrl
      // 标题
      this.imageTitle = item.title
      // 右侧列表的索引显示
      this.imageIndex = index
    },

    // 设置图片展示的大小
    infoImageWidthFn () {
      this.iconLoading = true
      this.imageEl.style.opacity = 0
      this.imageEl.style.width = 'auto'
      this.imageEl.style.transform = 'translateY(-50%) translateX(-50%)' + 'rotate('+ this.rotateIndex + 'deg)' + 'scale('+ this.scaleIndex +')'
      this.imageEl.onload = () => {
        // 如果图片的大于容器的宽度，则是在为80%
        if (this.imageEl.width > this.imageWidth - 100) {
          this.imageEl.style.width = '80%'
        } else {
          this.imageEl.style.width = 'auto'
        }
        this.imageEl.style.opacity = 1
        this.iconLoading = false
        this.onReductionFn ()
      }
    },

    // 图片上下切换
    onSwitchChange (type) {
      switch (type) {
          // 上一张
        case 'upper':
          this.imageIndex -= 1
          break
          // 下一张
        case 'next':
          this.imageIndex += 1
          break
      }
      if (this.imageIndex < 0) {
        this.imageIndex = this.isImageList.length - 1
      }
      if (this.imageIndex === this.isImageList.length) {
        this.imageIndex = 0
      }
      // 图片
      this.imageUrl = this.isImageList[this.imageIndex].isUrl
      // 标题
      this.imageTitle = this.isImageList[this.imageIndex].title
    },

    // 鼠标滚轮控制图片缩放
    onRollerFn () {
      let scrollFunc =  (e) => {
        let evt = e || window.event
        if (evt.wheelDelta) { // 兼容处理
          if (evt.wheelDelta > 0) { //当滑轮向上滚动时
            this.onScaleFn ('large')
          }
          if (evt.wheelDelta < 0) { //当滑轮向下滚动时
            this.onScaleFn ('small')
          }
        } else if (evt.detail) {  //Firefox滑轮事件
          if (evt.detail > 0) { //当滑轮向上滚动时
            this.onScaleFn ('large')
          }
          if (evt.detail < 0) { //当滑轮向下滚动时
            this.onScaleFn ('small')
          }
        }
      }
      if (this.imageEl.addEventListener) {
        this.imageEl.addEventListener('DOMMouseScroll', scrollFunc, { passive: false })
      }
      this.imageEl.onmousewheel = scrollFunc
    },

    // 放大、缩小
    onScaleFn (type) {
      // 放大
      if (type === 'large') {
        this.scaleIndex += 0.5
      }
      // 缩小
      if (type === 'small' && this.scaleIndex > 0.5) {
        this.scaleIndex -= 0.5
      }
      this.imageEl.style.transform = 'translateY(-50%) translateX(-50%)' + 'rotate('+ this.rotateIndex + 'deg)' + 'scale('+ this.scaleIndex +')'
    },

    // 左右旋转
    onRotateFn (type) {
      // 向右旋转
      if (type === 'right') {
        this.rotateIndex += 90
      }
      // 向左旋转
      if (type === 'left') {
        this.rotateIndex -= 90
      }
      this.imageEl.style.transform = 'translateY(-50%) translateX(-50%)' + 'rotate('+ this.rotateIndex + 'deg)' + 'scale('+ this.scaleIndex +')'
    },

    // 在新的浏览器窗口打开
    onOpenFn () {
      window.open(this.imageUrl)
    },

    // 还原
    onReductionFn () {
      this.rotateIndex = 0
      this.scaleIndex = 1
      this.imageEl.style.left = 'auto'
      this.imageEl.style.top = '50%'
      this.imageEl.style.transform = 'translateY(-50%) translateX(-50%)'
    },

    // 图片拖拽
    onPositionImgFn () {
      this.imageEl.onmousedown = (event) => {
        event = event || window.event
        let ol = event.clientX - this.imageEl.offsetLeft
        let ot = event.clientY - this.imageEl.offsetTop
        document.onmousemove = (event) => {
          event = event ||window.event
          let left = event.clientX - ol
          let top = event.clientY - ot
          this.imageEl.style.left = left + 'px'
          this.imageEl.style.top = top + 'px'
        }
        document.onmouseup = () => {
          document.onmousemove = null
          document.onmouseup = null
        }
        return false
      }
    },

    // 将右侧图片滚动到可视区域
    infoScrollIntoViewFn (el) {
      if (el) {
        el.scrollIntoView({
          behavior: 'smooth',
          block: 'center',
        })
      }
    },

    // 组件的回调事件
    onCallbackFn (type) {
      let parameter = {
        type: type, // 关闭：close，  下载：download
        imageUrl: this.imageUrl
      }
      if (type === 'close') {
        document.body.style.overflow = 'auto'
      }
      this.$emit('onImageViewerCallback', parameter)
    },

    // 监听浏览器窗口大小
    onResizeFn () {
      this.imageWidth = window.innerWidth
    },
  }
}
</script>
<style lang="scss" scoped>
.image-viewer-webpart {
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  right: 0;
  left: 0;
  font-size: 14px;
  z-index: 19960915;
  background-color: rgba(51, 51, 51, 0.95);

  /**
   * @ 顶部
   ************************************/
  .webpart-head {
    display: flex;
    justify-content: space-between;
    height: 50px;
    padding: 0 0 0 10px;
    color: #fff;
    background-color: #000000;
    .head-left {
      flex-shrink: 1;
      width: 300px;
      line-height: 50px;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
      i {
        margin-right: 5px;
      }
    }
    .head-right {
      i {
        font-size: 18px;
        cursor: pointer;
        width: 60px;
        height: 50px;
        line-height: 50px;
        text-align: center;
        transition: all .3s ease-in;
        &:hover {
          color: #000000;
          background-color: #fff;
        }
      }
    }
    .head-right-hover {
      color: #000000;
      background-color: #fff;
    }
  }

  /**
   * @ 图片容器
   ************************************/
  .webpart-image-cont {
    position: relative;
    height: calc(100vh - 50px);
    overflow: hidden;
    transition: all .3s ease-in;
    text-align: center;
    img {
      position: absolute;
      top: 50%;
      transform: translateY(-50%) translateX(-50%);
      transform-origin: center center;
      transition: transform 0.5s ease;
      cursor: pointer;
    }
    .el-icon-loading {
      font-size: 24px;
      color: #fff;
      position: absolute;
      top: 50%;
      transform: translateY(-50%) translateX(-50%);
    }
  }

  /**
   * @ 上下页
   ************************************/
  .webpart-nav-main {
    position: absolute;
    top: 48%;
    width: 40px;
    height: 80px;
    line-height: 80px;
    cursor: pointer;
    text-align: center;
    color: #fff;
    z-index: 19960916;
    transition: all .3s ease-in;
    background-color: rgba(0, 0, 0, 0.1);
    i {
      font-size: 18px;
    }
    &:hover {
      background-color: rgba(0, 0, 0, 0.5);
    }
  }
  .image-upper-main {
    left: 0;
    border-top-right-radius: 5px;
    border-bottom-right-radius: 5px;
  }
  .image-next-main {
    right: 0;
    border-top-left-radius: 5px;
    border-bottom-left-radius: 5px;
  }

  /**
   * @ 底部工具栏
   ************************************/
  .webpart-footer-main {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    width: fit-content;
    height: 50px;
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
    color: #fff;
    text-align: center;
    transition: all .3s ease-in;
    background-color: rgba(0, 0, 0, 0.5);
    i {
      font-size: 18px;
      cursor: pointer;
      width: 80px;
      height: 50px;
      line-height: 50px;
      text-align: center;
      transition: all .3s ease-in;
      &:hover {
        color: #000000;
        background-color: #fff;
      }
      &:nth-child(1) {
        border-top-left-radius: 5px;
      }
      &:nth-last-child(1) {
        border-top-right-radius: 5px;
      }
    }
  }

  /**
   * @ 右侧列表
   ************************************/
  .webpart-right-list {
    position: fixed;
    top: 50px;
    right: -300px;
    width: 300px;
    height: calc(100vh - 50px);
    overflow: hidden;
    box-sizing: border-box;
    padding: 0 10px 10px 10px;
    color: #fff;
    background-color: #333;
    transition: all .3s ease-in;
    .list-head {
      display: flex;
      justify-content: space-between;
      height: 30px;
      line-height: 30px;
      margin-bottom: 10px;
      border-bottom: 1px solid #636363;
      .lh-left {
        i {
          margin-right: 5px;
        }
      }
      .lh-right {
        font-size: 12px;
      }
    }
    .list-main {
      height: calc(100vh - 105px);
      overflow: hidden;
      overflow-y: auto;
      .image-list {
        margin-bottom: 10px;
        cursor: pointer;
        border: 1px solid #636363;
        padding: 5px;
        transition: all .3s ease-in;
        background-color: #242424;
        &:hover {
          background-color: #fff;
        }
        &:nth-last-child(1) {
          margin-bottom: 0;
        }
        img {
          width: 100%;
          height: 120px;
          border: 1px solid rgba(83,83,83,.3);
        }
      }
      .image-list-hover {
        background-color: #fff;
      }
    }
    .list-main::-webkit-scrollbar {
      width: 0;
      height: 0;
    }
  }
}
</style>